﻿#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

#include "mylib_parse.h"

static char latex_string[2048];

/*
* 明明是一行，中间有 \\
* 所以划分为多行
*/
void latex_multi_lines(char* fp, char* text)
{
	int ignore = 0;
	if (strstr(text, "matrix"))
		ignore = 1;
	else if (strstr(text, "\\begin"))
		ignore = 1;
	else if (strstr(text, "\\left"))
		ignore = 1;
	else if (strstr(text, "\\right"))
		ignore = 1;

	if (ignore) {
		sprintf(fp, "\n$$\n%s\n$$\n\n", text);
		return;
	}

	char* next = strstr(text, "\\\\");
	while (next) {
		*next = 0;
		sprintf(fp, "\n$$\n%s\n$$\n", text);
		fp = fp + strlen(text) + 8;
		text = next + 2;
		next = strstr(text, "\\\\");
	}
	//last line
	next = text + strlen(text) - 1;
	while (*next == ' ')
		next--;
	if (*next == '\\')
		*next = 0;
	if(text[0])
		sprintf(fp, "\n$$\n%s\n$$\n", text);
}

//{\text{Time Invariant & Scaling system }}
void write_latex_special(char* fp, char* text, char* head)
{
	char* ptr;
	ptr = strstr(text, "\\text");
	ptr = strchr(ptr, '&');
	if (ptr) {
		*ptr = 0;
		sprintf(fp, "\n$$\n%s\\&%s\\%s\n$$\n\n", text, ptr + 1, head);
	} else {
		sprintf(fp, "\n$$\n%s \\%s\n$$\n\n", text, head);
	}
}

//<span class="ztext-math" data-eeimg="1" data-tex=
// \[ F(x, y) = \begin {cases} 1 ... \]
static void handle_special(char* fp, char* text)
{
	char* head = strstr(text, "\\[");
	char* tail = strstr(text, "\\]");
	if (!head || !tail) {
		sprintf(fp, "\n$$\n%s\n$$\n\n", text);
		return;
	}

	head = head + 2;
	*tail = 0;
	sprintf(fp, "\n$$\n%s\n$$\n\n", head);
}

/*
* multi line
$$
	math
$$
inline: $math$
*/
static void write_latex(char* fp, char* text, int multiLine)
{
	char *tail, *head;
	size_t len;
	if (multiLine) {
		//\\\tag{1} to \tag{1}
		//\\  \tag{1} to \tag{1}
		tail = strstr(text, "\\tag");
		if (tail) {
			head = strstr(tail + 1, "tag");
			tail = head;
			while (1) {
				tail--;
				if (*tail == ' ' || *tail == '\\')
					continue;
				break;
			}
			*(tail + 1) = 0;
			//{\text{Time Invariant & Scaling system }}
			if (strstr(text, "\\text") && strchr(text, '&')) {
				write_latex_special(fp, text, head);
			} else {
				sprintf(fp, "\n$$\n%s \\%s\n$$\n\n", text, head);
			}
		}
		else {
			head = strstr(text, "\\\\");
			if (head)
				head = strstr(head + 2, "\\\\");

			if (head) {
				latex_multi_lines(fp, text);
			} else {
				head = strstr(text, "\\[");
				if (head)
					handle_special(fp, text);
				else
					sprintf(fp, "\n$$\n%s\n$$\n\n", text);
			}
		}
	} else {
		len = strlen(text);
		if(len == 1 && *text == ' ')
			return;
		sprintf(fp, " $%s$ ", text);
	}
}

// <span class="ztext-math" data-eeimg="1" data-tex="X(j\omega)">X(j\omega)</span>
char* create_latex_str(lxb_dom_element_t* node, size_t* len)
{
	char* str = latex_string;
	char* extra;
	size_t val_len;

	extra = (char*)lxb_dom_element_get_attribute(node, "data-tex", strlen("data-tex"), &val_len);
	if (!extra) {
		return NULL;
	}

	int new_line = 0;
	val_len = strlen(extra);
	if (strstr(extra, "{aligned}")) {
		new_line = 1;
	}
	else if (strstr(extra, "\\\\")) {
		new_line = 1;
	}
	else if (strstr(extra, "\\large")) {
		if (val_len > 20)
			new_line = 1;
	}
	else if (val_len > 40) {
		new_line = 1;
	}

	write_latex(latex_string, extra, new_line);

	if (len)
		*len = strlen(str);
	return latex_string;
}

void change_node_content(lxb_dom_element_t* el)
{
	lxb_char_t* str;
	size_t str_len;
	lxb_dom_node_t* node = lxb_dom_interface_node(el);
	str = lxb_dom_node_text_content(node, &str_len);

	lxb_dom_node_t* parent;
	parent = lxb_dom_node_parent(node);
	lxb_dom_text_t* text;
	lxb_html_document_t* doc;
	doc = lxb_html_interface_document(node->owner_document);

	char* latex;
	latex = create_latex_str(el, &str_len);
	if (!latex)
		return;
	text = lxb_dom_document_create_text_node(&doc->dom_document, latex, str_len);
	if (!text)
		return;
	lxb_dom_node_insert_before(node, lxb_dom_interface_node(text));
	lxb_dom_node_destroy(lxb_dom_interface_node(el));
}

//<span class=ztext-math data-eeimg=1 data-tex = h(t)>
void change_span_latex_nodes(lxb_dom_node_t* node)
{
	lxb_dom_element_t* element = NULL;
	lxb_dom_collection_t* collection;

	collection = get_nodes_by_tag(node, "span");
	if (!collection)
		return;

	size_t i;
	size_t len = lxb_dom_collection_length(collection);
	for (i = 0; i < len; i++) {
		element = lxb_dom_collection_element(collection, i);
		if (is_attr_value(element, "class", "ztext-math")) {
			change_node_content(element);
		}
	}

	lxb_dom_collection_destroy(collection, true);
}
